package jobscheduling.model;

/**
 * Liczy laczny czas wykonania wszystkich zadan w danym rozwiazaniu
 * 
 * @author Konrad Tendera
 * 
 */
public class SolutionEvaluator {

	/**
	 * oblicza czas po jakim zakoncza prace wszytskie maszyny w ustawianiu jak w
	 * solution
	 */
	public static int getEval(InputData data, int[] solution) {
		int works = data.getJobs();
		int machines = data.getMachines();
		int[][] endingTimes = new int[machines][works];
		// wyzeruj czasy zakonczenia
		for (int i = 0; i < works; i++)
			for (int j = 0; j < machines; j++)
				endingTimes[j][i] = 0;
		// zwroc czas zakonczenia ostatniego zadania na ostatniej maszynie
		return getEndingTime(solution, data, endingTimes, machines - 1, works - 1);
	}

	static private int getEndingTime(int[] solution, InputData data,
			int[][] endingTimes, int machine, int task) {

		if (endingTimes[machine][task] != 0) // gdy juz jest obliczony
			return endingTimes[machine][task];
		else {
			int thisTaskOnPrevMachineET = 0;
			int prevTaskOnThisMachineET = 0;
			if (task != 0) // czy nie pierwsze zadanie
				prevTaskOnThisMachineET = getEndingTime(solution, data,
						endingTimes, machine, task - 1);
			if (machine != 0) // czy nie pierwsza maszyna
				thisTaskOnPrevMachineET = getEndingTime(solution, data,
						endingTimes, machine - 1, task);
			// dane zadanie zacznie sie wykonywac na danej maszynie gdy
			// - skonczy sie poprzednie na tej maszynie
			// - aktualne zakonczy sie na poprzedniej maszynie
			// czas zakonczenia pozniejszego z powyzszych jest czasem
			// rozpoczecia
			endingTimes[machine][task] = Math.max(prevTaskOnThisMachineET,
					thisTaskOnPrevMachineET)
					+ data.data[machine][solution[task]];
			return endingTimes[machine][task];
		}
	}
}